#include "FileTransfer.h"
#include "FileReceiverServer.h"
#include "FileSender.h"

FileTransfer::FileTransfer(QObject* parent)
	: QObject(parent)
{
	mReceiverServer = new FileReceiverServer(this);
	connect(mReceiverServer, &FileReceiverServer::signalReceiveProgressChanged, this, &FileTransfer::signalReceiveProgressChanged);
	connect(mReceiverServer, &FileReceiverServer::signalFileReceiveFinished, this, &FileTransfer::signalFileReceiveFinished);
	connect(mReceiverServer, &FileReceiverServer::signalReceiveStart, this, &FileTransfer::signalReceiveStart);
	connect(mReceiverServer, &FileReceiverServer::signalReceiveError, this, &FileTransfer::signalReceiveError);

	qRegisterMetaType<FileTransferDef::sFile>("FileTransferDef::sFile");
	qRegisterMetaType<QList<FileTransferDef::sFile>>("QList<FileTransferDef::sFile>");
	qRegisterMetaType<FileTransferDef::eRecevieError>("FileTransferDef::eRecevieError");
	qRegisterMetaType<FileTransferDef::eSendState>("FileTransferDef::eSendState");
	qRegisterMetaType<FileTransferDef::eSendFileCmd>("FileTransferDef::eSendFileCmd");
	qRegisterMetaType<FileTransferDef::eRevFileCmd>("FileTransferDef::eRevFileCmd");
	qRegisterMetaType<FileTransferDef::sRevSavePath>("FileTransferDef::sRevSavePath");
}

FileTransfer::~FileTransfer()
{
	delete mReceiverServer;
	stopAll();
}

void FileTransfer::setSavePaths(const QList<FileTransferDef::sRevSavePath>& revSavePaths)
{
	mReceiverServer->setSavePaths(revSavePaths);
}

bool FileTransfer::start(int port)
{
	return mReceiverServer->listen(QHostAddress::Any, port);
}

void FileTransfer::sendFiles(const QString& ip, const QList<FileTransferDef::sFile>& files)
{
	FileSender* fileSender = nullptr;
	if (!mIpAndSenderMap.contains(ip))
	{
		fileSender = getFileSenderManager()->createSender(ip, mReceiverServer->serverPort());
		connect(fileSender, &FileSender::signalSendError, this, [=](const QString& error) {
			emit signalSendError(ip, error);
			});
		connect(fileSender, &FileSender::signalSendChanged, this, [=](const FileTransferDef::sFile& file) {
			emit signalSendChanged(ip, file);
			});
		connect(fileSender, &FileSender::signalSendFinished, this, [=](const FileTransferDef::sFile& file) {
			emit signalSendFinished(ip, file);
			});
		connect(fileSender, &FileSender::signalSendPrograss, this, [=](qreal percentage) {
			emit signalSendPrograss(ip, percentage);
			});
		connect(fileSender, &FileSender::signalSendAllFinished, this, [=]() {
			emit signalSendAllFinished(ip);
			});
		connect(fileSender, &FileSender::signalClose, this, [=]() {
			mIpAndSenderMap.remove(ip);
			getFileSenderManager()->destroySender(fileSender);
			});
		mIpAndSenderMap.insert(ip, fileSender);
	}
	else
	{
		fileSender = mIpAndSenderMap.value(ip);
	}
	fileSender->send(files);
}

void FileTransfer::stop(const QString& ip)
{
	FileSender* fileSender = mIpAndSenderMap.value(ip);
	if (fileSender)
    {
        fileSender->stop();
		emit signalSendStop(ip);
    }
}

void FileTransfer::stopAll()
{
	QMap<QString, FileSender*> ipAndSenderMap = mIpAndSenderMap;
	for (auto itr = ipAndSenderMap.begin(); itr != ipAndSenderMap.end(); ++itr)
	{
		itr.value()->stop();
		emit signalSendStop(itr.key());
	}
}